package br.com.rhinovet.faces;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import org.primefaces.context.RequestContext;

import br.com.rhinovet.entidade.Procedimento;
import br.com.rhinovet.entidade.SubCategoria;
import br.com.rhinovet.enumgeral.CategoriaProcedimento;
import br.com.rhinovet.logica.contract.DefaultLogicaContract;
import br.com.rhinovet.util.DoubleUtil;
import br.com.rhinovet.util.FacesUtil;
import br.com.rhinovet.util.StringUtil;

@ManagedBean(name="procedimentoFaces")
@ViewScoped
public class ProcedimentoFaces extends FacesUtil {
	
	private static final long serialVersionUID = 1L;

	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<Procedimento> logicaProcedimento;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<SubCategoria> logicaSubCategoria; 
	
	private List<SubCategoria> listaSubCategoria = new ArrayList<>();
	private Boolean exibirSubCategoria = false;
	
	private Procedimento procedimento = new Procedimento();
	private List<Procedimento> listaProcedimento = new ArrayList<>();
	private String procedimentoBusca;

	public ProcedimentoFaces() {
	}
	
	@PostConstruct
	public void init() {
		this.buscarProcedimento();
	}
	
	@PreDestroy
	public void finalizar() {
		getSession().setAttribute("isPopup", null);
	}


	public void adicionar() {
		try {
			if (validaCampos()) {
				logicaProcedimento.adicionar(procedimento);
				adicionarMensagem("Procedimento adicionado com sucesso");
				this.buscarProcedimento();
				fecharModal("dialogProcedimento");
			} else {
				return;
			}
			
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao adicionar o Procedimento");
		}
	}
	
	public void prepararAdicionar() {
		this.procedimento = new Procedimento();
		abrirModal("dialogProcedimento");
	}
	
	public void selecionarRegistro(Long idArea, boolean editar) {
		try {
			this.procedimento = logicaProcedimento.obterPorId(Procedimento.class,idArea);
			
			if (editar) {
				abrirModal("dialogProcedimento");
			} else {
				abrirModal("dialogExcluir");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void editar() {
		try {
			if (validaCampos()) {
				logicaProcedimento.editar(this.procedimento);
				adicionarMensagem("Procedimento editado com sucesso");
				fecharModal("dialogProcedimento");
				this.buscarProcedimento();
			} else {
				return;
			}
			
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao editar o Procedimento");
		}
	}
	
	public void remover() {
		try {
			logicaProcedimento.remover(Procedimento.class, this.procedimento.getId());
			adicionarMensagem("Procedimento removido com sucesso");
			fecharModal("dialogExcluir");
			this.buscarProcedimento();
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao remover o Procedimento");
		}
	}
	
	public void buscarProcedimento() {
		if (listaProcedimento != null) {
			this.listaProcedimento.clear();
		}
		String campoBusca = "nome";
		String campoOrdenacao = "categoriaProcedimento";
		try {
			if (!StringUtil.textoPreenchido(procedimentoBusca)) {
				this.listaProcedimento =  logicaProcedimento.buscarTodos(Procedimento.class, campoOrdenacao, campoBusca);
			} else {
				this.listaProcedimento = logicaProcedimento.buscarPorCampo(Procedimento.class, campoBusca, procedimentoBusca, campoOrdenacao, campoBusca);
			}
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao buscar as informações");
		}
	}
	
	public boolean validaCampos() {
		boolean valido = true;
		
		if (!StringUtil.textoPreenchido(this.procedimento.getNome())) {
			adicionarMensagem("O campo procedimento é obrigatório");
			valido = false;
		}
		return valido;
	}
	
	public List<Procedimento> autoComplete(String query) {
		List<Procedimento> suggestions = new ArrayList<>();
		if (query.length() > 1) {
			try {
				suggestions = logicaProcedimento.buscarPorCampo(Procedimento.class, "nome", query, "nome", null);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return suggestions;
    }
	
	public void calculaValorPequeno() {
		if (this.procedimento.getPorcentagemComissaoPequeno() != null) {
			Double valorLiquido = DoubleUtil.calcularValorLiquido(this.procedimento.getValorTotalPequeno(), this.procedimento.getPorcentagemComissaoPequeno());
			this.procedimento.setValorLiquidoPequeno(valorLiquido);
		}
	}
	
	public void calcularPorcentagemPequeno() {
		if (this.procedimento.getValorTotalPequeno() != null && this.procedimento.getValorLiquidoPequeno() != null) {
			Double porcentagem = DoubleUtil.calcularPorcentagem(this.procedimento.getValorTotalPequeno(), this.procedimento.getValorLiquidoPequeno());
			this.procedimento.setPorcentagemComissaoPequeno(porcentagem);
		}
	}
	
	public void calculaValorGrande() {
		if (this.procedimento.getPorcentagemComissaoGrande() != null) {
			Double valorLiquido = DoubleUtil.calcularValorLiquido(this.procedimento.getValorTotalGrande(), this.procedimento.getPorcentagemComissaoGrande());
			this.procedimento.setValorLiquidoGrande(valorLiquido);
		}
	}
	
	public void calcularPorcentagemGrande() {
		if (this.procedimento.getValorTotalGrande() != null && this.procedimento.getValorLiquidoGrande() != null) {
			Double porcentagem = DoubleUtil.calcularPorcentagem(this.procedimento.getValorTotalGrande(), this.procedimento.getValorLiquidoGrande());
			this.procedimento.setPorcentagemComissaoGrande(porcentagem);
		}
	}
	
	public List<CategoriaProcedimento> getListaCategoriaProcedimento() {
		List<CategoriaProcedimento> listaCategoriaProcedimento = Arrays.asList(CategoriaProcedimento.values());
		return listaCategoriaProcedimento;
	}

	public void buscarSubCategoria() {
		
		CategoriaProcedimento procedimentoSelecionado = this.procedimento.getCategoriaProcedimento();
		
		try {
			listaSubCategoria = logicaSubCategoria.buscarPorCampo(SubCategoria.class, "categoriaProcedimento", procedimentoSelecionado.name(), "nomeSubCategoria", null);
			
			if (listaSubCategoria.isEmpty()) {
				exibirSubCategoria = false;
			} else {
				exibirSubCategoria = true;
			}
			
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao buscar as Subcategorias");
		}
		
	}
	
    public void exibirDialogProcedimento() {
    	abrirDialogFramework("procedimento", true);
    }

	public void retornoProcedimento(Procedimento procedimento) {
        RequestContext.getCurrentInstance().closeDialog(procedimento);
    }

	public void setlogicaProcedimento(DefaultLogicaContract<Procedimento> logicaProcedimento) {
		this.logicaProcedimento = logicaProcedimento;
	}

	public List<Procedimento> getListaProcedimento() {
		return listaProcedimento;
	}

	public void setListaProcedimento(List<Procedimento> listaProcedimento) {
		this.listaProcedimento = listaProcedimento;
	}

	public String getProcedimentoBusca() {
		return procedimentoBusca;
	}

	public void setProcedimentoBusca(String ProcedimentoBusca) {
		this.procedimentoBusca = ProcedimentoBusca;
	}

	public Procedimento getProcedimento() {
		return procedimento;
	}

	public void setProcedimento(Procedimento Procedimento) {
		this.procedimento = Procedimento;
	}

	public List<SubCategoria> getListaSubCategoria() {
		return listaSubCategoria;
	}

	public void setListaSubCategoria(List<SubCategoria> listaSubCategoria) {
		this.listaSubCategoria = listaSubCategoria;
	}

	public Boolean getExibirSubCategoria() {
		return exibirSubCategoria;
	}

	public void setExibirSubCategoria(Boolean exibirSubCategoria) {
		this.exibirSubCategoria = exibirSubCategoria;
	}

	public void setLogicaSubCategoria(DefaultLogicaContract<SubCategoria> logicaSubCategoria) {
		this.logicaSubCategoria = logicaSubCategoria;
	}
	
	
	
}